package aash.catalog.views;

import aash.catalog.controller.CatalogController;
import aash.catalog.event.ExplorerListener;
import aash.catalog.event.PropertyChangedEvent;
import aash.catalog.views.button.PropertyButton;
import aash.catalog.views.button.SaveButton;
import aash.catalog.views.component.AashComponent;
import aash.catalog.views.field.PropertyField;
import aash.catalog.views.label.PropertyLabel;
import aash.catalog.views.menubar.MenuBarExplorer;
import aash.catalog.views.panel.PropertyPanel;
import aash.utils.element.CatalogProperty;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.ImageIcon;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import org.apache.log4j.Logger;

/**
 * Main view of AashCatalog Project.
 * @author Aashintan
 */
public class MainView extends AbstractView implements MouseListener, ActionListener, ExplorerListener {
    /**
     * Logger.
     */
    private static Logger log = Logger.getLogger(MainView.class.getName());
    /**
     * Percentage of full background height in the screen.
     */
    private final double bgHPerc = 0.93;
    /**
     * Current resolution : Height.
     */
    private int resH = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
    /**
     * Current resolution : Width.
     */
    private int resW = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    /**
     * The frame (window).
     */
    private JFrame frame = null;
    /**
     * The panel.
     */
    private JLayeredPane contentPane = null;
    /**
     * The background.
     */
    private JLabel background = null;
    /**
     * The background image.
     */
    private ImageIcon backgroundIcon = null;
    /**
     * Background path.
     */
    private final String bgPath = "config/background.png";
    /**
     * The property Panel.
     */
    private PropertyPanel propertyPanel = null;
    /**
     * List of JLabels.
     */
    private ArrayList < JLabel > labels;
    /**
     * List of JFormattedTextField.
     */
    private ArrayList < JFormattedTextField > fields;
    /**
     * The left button.
     */
    private PropertyButton leftButton = null;
    /**
     * The right button.
     */
    private PropertyButton rightButton = null;
    /**
     * The save button.
     */
    private SaveButton saveButton = null;
    /**
     * The picture label.
     */
    private JLabel picture = null;
    /**
     * The picture image.
     */
    private ImageIcon pictureIcon = null;
    /**
     * The alpha medium level (50%).
     */
    private final float alphaMedium = 0.5F;
    /**
     * The alpha high level (99%).
     */
    private final float alphaHigh = 0.99F;
    /**
     * Fields available.
     */
    private ArrayList < String > fieldKeys;
    /**
     * Lines of data.
     */
    private HashMap < String, CatalogProperty > lines;

    /**
     * Class constructor.
     * @param title of the window
     * @param ccController of the view
     * @param hmLines Lines of data.
     * @param alFieldKeys Fields available
     */
    public MainView(final CatalogController ccController, final String title,
        final HashMap < String, CatalogProperty > hmLines, final ArrayList < String > alFieldKeys) {
        super(ccController);
        lines = hmLines;
        fieldKeys = alFieldKeys;
        buildFrame(title);
    }

    /**
     * Build the frame.
     * @param title of the frame
     */
    private void buildFrame(final String title) {
        frame = new JFrame();
        contentPane = new JLayeredPane();
        // Setting the background
        backgroundIcon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(bgPath).getScaledInstance(resW,
            (int) (bgHPerc * resH), Image.SCALE_DEFAULT));
        background = new JLabel();
        background.setBounds(0, 0, backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight());
        background.setIcon(backgroundIcon);
        contentPane.add(background, JLayeredPane.DEFAULT_LAYER);
        // Adding the property panel
        propertyPanel = new PropertyPanel();
        propertyPanel.setAlpha(alphaMedium);
        propertyPanel.addMouseListener(this);
        contentPane.add(propertyPanel, JLayeredPane.PALETTE_LAYER);
        initLines();
        // Adding the left button
        leftButton = new PropertyButton(propertyPanel, "left_1");
        leftButton.setAlpha(alphaMedium);
        leftButton.addMouseListener(this);
        contentPane.add(leftButton, JLayeredPane.PALETTE_LAYER);
        // Adding the right button
        rightButton = new PropertyButton(propertyPanel, "right_1");
        rightButton.setAlpha(alphaMedium);
        rightButton.addMouseListener(this);
        contentPane.add(rightButton, JLayeredPane.PALETTE_LAYER);
        // Adding save button
        saveButton = new SaveButton(propertyPanel, "Enregistrer");
        saveButton.setAlpha(alphaMedium);
        saveButton.setActionCommand(AashActionCommand.ACTION_SAVE);
        saveButton.addMouseListener(this);
        saveButton.addActionListener(this);
        contentPane.add(saveButton, JLayeredPane.PALETTE_LAYER);
        // Frame operations
        frame.setBounds(0, 0, background.getWidth(), background.getHeight());
        frame.setJMenuBar(new MenuBarExplorer(this));
        frame.setContentPane(contentPane);
        frame.setTitle(title);
        frame.pack();
        frame.setMinimumSize(new Dimension(Toolkit.getDefaultToolkit().getScreenSize().width, (int) (Toolkit
            .getDefaultToolkit().getScreenSize().height * 0.963)));
        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(final WindowEvent e) {
                getController().close();
                System.exit(0);
            }
        });
        frame.setVisible(true);
    }

    /**
     * @Override
     */
    public final void close() {
        frame.dispose();
    }

    /**
     * @Override
     */
    public final void display() {
        frame.setVisible(true);
    }

    /**
     * @Override
     * @param event containing value
     */
    public final void propertyChanged(final PropertyChangedEvent event) {
        // field.setValue(event.getProperty().getValue());
    }

    /**
     * Repaint this view.
     */
    public final void repaint() {
        frame.repaint();
        System.out.println("repaint");
    }

    /**
     * @param e event
     * @Override
     */
    public final void mouseClicked(final MouseEvent e) {
        Object source = e.getSource();
        if (source.equals(leftButton)) {
            getController().notifyListBackward();
        }
        if (source.equals(rightButton)) {
            getController().notifyListForward();
        }
    }

    /**
     * @param e event
     * @Override
     */
    public final void mouseEntered(final MouseEvent e) {
        Object source = e.getSource();
        if (source.equals(saveButton) || source.equals(leftButton) || source.equals(rightButton)
            || source.equals(propertyPanel)) {
            ((AashComponent) source).setAlpha(alphaHigh);
            ((AashComponent) source).repaint();
            // System.out.println("enter : " + ((AashComponent) source).getColor().toString());
        }
    }

    /**
     * @param e event
     * @Override
     */
    public final void mouseExited(final MouseEvent e) {
        Object source = e.getSource();
        if (source.equals(saveButton) || source.equals(leftButton) || source.equals(rightButton)
            || source.equals(propertyPanel)) {
            ((AashComponent) source).setAlpha(AashComponent.ALPHA_50);
            ((AashComponent) source).repaint();
            // System.out.println("exit : " + ((AashComponent) source).getColor().toString());
        }
    }

    /**
     * @param e event
     * @Override
     */
    public final void mousePressed(final MouseEvent e) {
        Object source = e.getSource();
        if (source.equals(saveButton) || source.equals(leftButton) || source.equals(rightButton)) {
            ((AashComponent) source).setAlpha(AashComponent.ALPHA_80);
        }
    }

    /**
     * @param e event
     * @Override
     */
    public final void mouseReleased(final MouseEvent e) {
        Object source = e.getSource();
        if (source.equals(saveButton) || source.equals(leftButton) || source.equals(rightButton)) {
            ((AashComponent) source).setAlpha(AashComponent.ALPHA_99);
        }
    }

    /**
     * @Override
     * @param ae event
     */
    public final void actionPerformed(final ActionEvent ae) {
        if (ae.getActionCommand().equals(AashActionCommand.ACTION_NEW_DB)) {
            getController().notifyNewDbView();
        }
        if (ae.getActionCommand().equals(AashActionCommand.ACTION_OPEN_DB)) {
            getController().notifyOpenDbView();
        }
        if (ae.getActionCommand().equals(AashActionCommand.ACTION_CLOSE_DB)) {
            getController().notifyCloseDB();
        }
        if (ae.getActionCommand().equals(AashActionCommand.ACTION_SAVE)) {
            getController().notifySave(
                new String[] { fields.get(0).getText(), fields.get(1).getText(), fields.get(2).getText(),
                    fields.get(3).getText(), fields.get(4).getText() });
        }
    }

    /**
     * Initialize the lines of property.
     */
    private void initLines() {
        int i = 0;
        labels = new ArrayList < JLabel >();
        fields = new ArrayList < JFormattedTextField >();
        PropertyField pf;
        while (i < fieldKeys.size()) {
            labels.add(new PropertyLabel(lines.get(fieldKeys.get(i)).getName(), propertyPanel, i));
            pf = new PropertyField(fieldKeys.get(i), propertyPanel, i, lines.get(fieldKeys.get(i)).getValue());
            pf.addActionListener(this);
            fields.add(pf);
            contentPane.add(labels.get(i), JLayeredPane.MODAL_LAYER);
            contentPane.add(fields.get(i), JLayeredPane.MODAL_LAYER);
            i++;
        }
    }
}
